package com.zdkj.subway.support.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.common.core.exceltools.MultipartFileToFile;
import com.zdkj.common.core.util.R;
import com.zdkj.common.data.mybatis.wrapper.CustomQueryWrapper;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.annotation.Inner;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.support.dto.in.SwParamStationDTO;
import com.zdkj.subway.support.dto.out.StationDetailDTO;
import com.zdkj.subway.support.entity.SwParamStation;
import com.zdkj.subway.support.service.SwParamLineService;
import com.zdkj.subway.support.service.SwParamStationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;




/**
 * 车站设置表
 *
 * @author cui_com
 * @date 2020-01-08 17:13:42
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/swparamstation")
@Api(value = "swparamstation", tags = "车站设置表管理")
public class SwParamStationController {

    private static final Logger LOGGER = LoggerFactory.getLogger(SwParamStationController.class);
    private final SwParamStationService swParamStationService;
	private final SwParamLineService swPmLineService;

	


    @ApiOperation(value = "详细分页查询(带主记录信息)", notes = "详细分页查询(带主记录信息)")
    @GetMapping("/detail/page")
    public R getSwStAlterLogDetailPage(Page page, StationDetailDTO stationDetailDTO) {
        return R.ok(swParamStationService.queryStationDetailByPage(
                page, new CustomQueryWrapper(SwParamStation.class)
                        .addDTO(stationDetailDTO)
                        .addAlis("s")
                        .addDelFlag(Boolean.TRUE)
                        .init()));
    }

    /**
     * 分页查询
     *
     * @param page           分页对象
     * @param swParamStation 车站设置表
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page")
    public R getSwParamStationPage(Page page, SwParamStation swParamStation) {
        return R.ok(swParamStationService.page(page, Wrappers.query(swParamStation).orderByAsc("sort")));
    }


    /**
     * 通过id查询车站设置表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}")
    public R getById(@PathVariable("id") Integer id) {
        return R.ok(swParamStationService.getById(id));
    }

    /**
     * 通过code查询车站设置表
     *
     * @param code code
     * @return R
     */
    @ApiOperation(value = "通过code查询", notes = "通过code查询")
    @GetMapping("/byCode/{code}")
    public R getByCode(@PathVariable("code") String code) {
        SwParamStation swParamStation = new SwParamStation();
        swParamStation.setCode(code);
        return R.ok(swParamStationService.getOne(Wrappers.query(swParamStation)));
    }

    /**
     * 通过name查询车站设置表
     *
     * @param name name
     * @return R
     */
    @ApiOperation(value = "通过name查询", notes = "通过name查询")
    @PostMapping("/byName")
    public R getByName(@RequestBody String name) {
        SwParamStation swParamStation = new SwParamStation();
        swParamStation.setName(name);
        return R.ok(swParamStationService.getOne(Wrappers.query(swParamStation)));
    }

    /**
     * 新增车站设置表
     *
     * @param swParamStation 车站设置表
     * @return R
     */
    @ApiOperation(value = "新增车站设置表", notes = "新增车站设置表")
    @SysLog("新增车站设置表")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('support_sw_param_station_add')")
    public R save(@RequestBody SwParamStationDTO swParamStation) {
        if (StringUtils.isNotBlank(swParamStation.getCode())) {
            if (CollectionUtil.isNotEmpty(swParamStationService.list(
                    Wrappers.<SwParamStation>query().lambda()
                            .eq(SwParamStation::getLineCode, swParamStation.getLineCode())
                            .eq(SwParamStation::getCode, swParamStation.getCode())))
            ) {
                return R.failed(swParamStation.getLineCode()+"号线车站编码为"+swParamStation.getCode()+"的数据已存在,相同线路车站的编码不允许重复");
            }
        }

        if (StringUtils.isNotBlank(swParamStation.getName())) {
            if (CollectionUtil.isNotEmpty(swParamStationService.list(
                    Wrappers.<SwParamStation>query().lambda()
                            .eq(SwParamStation::getLineCode, swParamStation.getLineCode())
                            .eq(SwParamStation::getName, swParamStation.getName())))
            ) {
                return R.failed(swParamStation.getLineCode()+"号线车站名称为"+swParamStation.getName()+"的数据已存在,相同线路车站的名称不允许重复");
            }
        }

        SwParamStation defaultObj = ObjectUtils.getDefaultObj(SwParamStation.class);
        BeanUtils.copyProperties(swParamStation, defaultObj);
        return R.ok(swParamStationService.save(defaultObj));
    }

    /**
     * 修改车站设置表
     *
     * @param swParamStation 车站设置表
     * @return R
     */
    @ApiOperation(value = "修改车站设置表", notes = "修改车站设置表")
    @SysLog("修改车站设置表")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('support_sw_param_station_edit')")
    public R updateById(@RequestBody SwParamStationDTO swParamStation) {
        if (StringUtils.isNotBlank(swParamStation.getCode())) {
            List<SwParamStation> paramStation = swParamStationService.list(Wrappers.<SwParamStation>query().lambda()
                            .eq(SwParamStation::getLineCode, swParamStation.getLineCode())
                            .eq(SwParamStation::getCode, swParamStation.getCode()));
            if (CollectionUtil.isNotEmpty(paramStation)) {
                for(SwParamStation item : paramStation){
                    if(!Objects.equals(swParamStation.getId(),item.getId())){
                        return R.failed(swParamStation.getLineCode()+"号线车站编码为"+swParamStation.getCode()+"的数据已存在,相同线路车站的编码不允许重复");
                    }
                }
            }
        }

        if (StringUtils.isNotBlank(swParamStation.getName())) {
            List<SwParamStation> paramStation = swParamStationService.list(Wrappers.<SwParamStation>query().lambda()
                            .eq(SwParamStation::getLineCode, swParamStation.getLineCode())
                            .eq(SwParamStation::getName, swParamStation.getName()));
            if (CollectionUtil.isNotEmpty(paramStation)) {
                for(SwParamStation item : paramStation){
                    if(!Objects.equals(swParamStation.getId(),item.getId())){
                        return R.failed(swParamStation.getLineCode()+"号线车站名称为"+swParamStation.getName()+"的数据已存在,相同线路车站的名称不允许重复");
                    }
                }
            }
        }
        SwParamStation obj = new SwParamStation();
        BeanUtils.copyProperties(swParamStation, obj);
        return R.ok(swParamStationService.updateById(obj));
    }

    /**
     * 通过id删除车站设置表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除车站设置表", notes = "通过id删除车站设置表")
    @SysLog("通过id删除车站设置表")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('support_sw_param_station_del')")
    public R removeById(@PathVariable Integer id) {
        return R.ok(swParamStationService.removeById(id));
    }

    /**
     * 车站字典接口
     *
     * @return R
     */
    @ApiOperation(value = "线路字典接口", notes = "线路字典接口")
    @GetMapping("/dict")
    public R getAll() {
        return R.ok(swParamStationService.list());
    }
	
    /**
     * 车站字典接口,区分一期二期
     *
     * @return R
     */
    @ApiOperation(value = "线路字典接口,区分一期二期", notes = "线路字典接口,区分一期二期")
    @GetMapping("/dictvlinecode")
    public R getVlinecodeAll() {
        return R.ok(swParamStationService.getVlinelist());
    }

    /**
     * 某一线路车站字典接口
     *
     * @return R
     */
    @ApiOperation(value = "某一线路车站字典接口,区分一期二期", notes = "某一线路车站字典接口,区分一期二期")
    @GetMapping("/dictvlinecode/{code}")
    public R getAllByVLineCode(@PathVariable String code) {
        SwParamStation swParamStation = new SwParamStation();
        swParamStation.setVlineCode(code);
        return R.ok(swParamStationService.list(Wrappers.query(swParamStation)));
    }
    /**
     * 线路字典内部接口
     *
     * @return R
     */
    @ApiOperation(value = "线路字典内部接口", notes = "线路字典内部接口")
    @GetMapping("/dictInner")
    @Inner
    public R getAllInner() {
        return R.ok(swParamStationService.list());
    }

    /**
     * 某一线路车站字典接口
     *
     * @return R
     */
    @ApiOperation(value = "某一线路车站字典接口", notes = "某一线路车站字典接口")
    @GetMapping("/dict/{code}")
    public R getAllByLineCode(@PathVariable String code) {
        SwParamStation swParamStation = new SwParamStation();
        swParamStation.setLineCode(code);
        return R.ok(swParamStationService.list(Wrappers.query(swParamStation).orderByAsc("sort")));
    }

    /**
     * 导入车站基础参数信息
     *
     * @param file
     * @return
     */
   /*
	@ApiOperation(value = "导入车站基础参数信息", notes = "导入车站基础参数信息")
    @SysLog("导入车站基础参数信息")
    @PostMapping("/import")
    public R importExcel(@RequestParam("file") MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(), SwParamReceipt.class,
                    new UploadDataListener(swParamStationService, SwParamStation.class)).sheet().doRead();
            return R.ok("导入成功");
        } catch (IOException e) {
            log.info(e.getMessage());
            return R.ok("导入失败");
        }
    }*/

    /**
     * 通过name和lineCode查询车站code
     * @param name
     * @param lineCode
     * @return
     */
    @ApiOperation(value = "通过name和lineCode查询车站code", notes = "通过name和lineCode查询车站code")
    @GetMapping("/name/byNameAndLineCode/{name}/{lineCode}")
    public R getCodeByNameAndLineCode(@PathVariable("name")String name, @PathVariable("lineCode")String lineCode){
        return R.ok(swParamStationService.getCodeByNameAndLineCode(name,lineCode));
    };

	/**
     * 导入车站
     *
     * @param file
     * @return
     */
    @ApiOperation(value = "导入车站", notes = "导入车站")
    @SysLog("导入车站")
    @PostMapping("/import")
    public R importExcel(@RequestParam("file") MultipartFile file) {
        try {
            PigxUser pigxUser = SecurityUtils.getUser();
		    List<SwParamStation> swStStationList = new ArrayList<>();
		    final File excelFile = MultipartFileToFile.multipartFileToFile(file);
		    List<Map<Integer, String>> listMap = EasyExcel.read(excelFile).sheet().headRowNumber(2).doReadSync();
		    if (CollectionUtil.isNotEmpty(listMap)) {
                MultipartFileToFile.delteTempFile(excelFile);
                int iCount = 0;
                for (int m = 0; m < listMap.size(); m++) {
                    Map<Integer, String> data = listMap.get(m);
                    // 返回每条数据的键值对 key表示所在的列位置 value表示所在列的值
                    LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
                    iCount ++;

                    SwParamStation stationVo = new SwParamStation();

                    if(StringUtils.isNotEmpty(data.get(0).trim())){
                        String lineCode = getLineCode(data.get(0).trim());
                        if(StringUtils.isEmpty(lineCode)){
                          return R.failed("请检查 第" + (m+3) +"行 线路名称是否在线路信息中存在！");
                           //continue;
                        }

                        String stationName = data.get(1);
                        if(StringUtils.isEmpty(stationName)){
                          return R.failed("请检查 第" + (m+3) +"行 车站名称没有填写！");
                          //continue;
                        }
                        stationName = stationName.trim();

                        String stationCode = data.get(2);
                        if(StringUtils.isEmpty(stationCode)){
                         return R.failed("请检查 第" + (m+3) +"行 车站编码没有填写！");
                         // continue;
                        }
                        stationCode = stationCode.trim();

                        String englishName = data.get(3);
                        if(StringUtils.isEmpty(englishName)){
                           return R.failed("请检查 第" + (m+3) +"行 车站英文名没有填写！");
                          //continue;
                        }
                        englishName = englishName.trim();

                        String ipAddress = data.get(4);
                        if(StringUtils.isEmpty(ipAddress)){
                          ipAddress="";
                        }
                        ipAddress = ipAddress.trim();

                        String lcIpaddress = data.get(5);
                        if(StringUtils.isEmpty(lcIpaddress)){
                          lcIpaddress ="";
                        }
                        lcIpaddress = lcIpaddress.trim();

                        String sort = String.valueOf(data.get(6));
                        if(StringUtils.isEmpty(sort)){
                          sort ="1";
                        }

                        String vlineCode = data.get(7);
                        if(StringUtils.isEmpty(vlineCode)){
                           return R.failed("请检查 第" + (m+3) +"行 虚拟线路编号没有填写！");
                          //continue;
                        }
                        vlineCode = vlineCode.trim();



                        //根据线路站点和TVM编号判断是否存在

                        QueryWrapper<SwParamStation> queryWrapper=new QueryWrapper<>();
                        queryWrapper.eq("line_code",lineCode);
                        queryWrapper.eq("code",stationCode);
                        //queryWrapper.ge("name",stationName);

                        List<SwParamStation> list = swParamStationService.list(queryWrapper);

                        //不存在添加
                        if(list==null || list.size()==0){
                            stationVo.setName(stationName);
                            stationVo.setCode(stationCode);
                            stationVo.setEnglishName(englishName);
                            stationVo.setIpAddress(ipAddress);
                            stationVo.setLcIpAddress(lcIpaddress);
                            stationVo.setSort(Integer.parseInt(sort));
                            stationVo.setActive(true);
                            stationVo.setLineCode(lineCode);
                            stationVo.setVlineCode(vlineCode);

                            stationVo.setDelFlag("0");
                            stationVo.setDeptId(pigxUser.getDeptId());
                            stationVo.setCreatorId(pigxUser.getId());
                            stationVo.setCreatorName(pigxUser.getNikeName());
                            stationVo.setCreateTime(LocalDateTime.now());
                            swStStationList.add(stationVo);
                            //swParamStationService.save(stationVo);
                        }else {//存在修改
                            stationVo = list.get(0);
                            stationVo.setName(stationName);
                            stationVo.setCode(stationCode);
                            stationVo.setEnglishName(englishName);
                            stationVo.setIpAddress(ipAddress);
                            stationVo.setLcIpAddress(lcIpaddress);
                            stationVo.setSort(Integer.parseInt(sort));
                            stationVo.setActive(true);
                            stationVo.setLineCode(lineCode);
                            stationVo.setVlineCode(vlineCode);
                            stationVo.setDelFlag("0");
                            swStStationList.add(stationVo);
                            //swParamStationService.updateById(stationVo);

                        }
                    }
                }
            }
            if(CollectionUtil.isNotEmpty(swStStationList)){
                return R.ok(swParamStationService.saveOrUpdateBatch(swStStationList));
            }else{
                return R.failed("导入失败，没有符合要导入的数据,请检查导入的数据！");
            }
        } catch (Exception e) {
            log.info(e.getMessage());
            return R.failed("导入失败");
        }
    }

	/**
	 * 下载模板
	 * @param
	 * @return
	 * @throws
	 */
	@ApiOperation(value = "下载模板", notes = "下载模板")
	@GetMapping("/exportTamplate")
	public void exportTamplateKY(HttpServletResponse response) {
		String  verifyConfirmName = "车站信息导入模板";
		String  tableName = "sw_param_station";

		BufferedInputStream br = null;
		OutputStream out = null;
		try {
			response.reset(); // 非常重要
			response.setContentType("application/vnd.ms-excel");
			response.setCharacterEncoding("utf-8");
			final String fileName = URLEncoder.encode(verifyConfirmName, "UTF-8");
			response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xls");

			br =  new BufferedInputStream(this.getClass().getResourceAsStream("/static/excel/template/import/" + tableName + ".xls"));

			byte[] buf = new byte[1024];
			int len = 0;

			out = response.getOutputStream();
			while ((len = br.read(buf)) > 0) {
				out.write(buf, 0, len);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(out != null) {
				try {
					out.close();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
			if(br != null){
				try {
					br.close();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
		}
	}

    //查询线路
	private  String getLineCode(String lineName) {
		if(StringUtils.isNotEmpty(lineName)){
			return swPmLineService.getCodeByName(lineName);
		}
		return "";
	}
	 //查询车站编号
	/*
	private  String getStationCode(String lineCode,String stationName) {
		if(StringUtils.isNotEmpty(stationName)){
			return this.getCodeByNameAndLineCode(stationName,lineCode);
		}
		return "";
	}*/
}
